package bb.lanxing.activity.sport;

import static bb.lanxing.util.MapUtil.drawSportLushu;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.map.TextureMapView;
import com.baidu.mapapi.model.LatLng;
import com.blankj.utilcode.util.ConvertUtils;
import com.github.mikephil.charting.utils.Utils;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.mylhyl.circledialog.CircleDialog;

import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.cardview.widget.CardView;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import bb.lanxing.App;
import bb.lanxing.R;
import bb.lanxing.activity.base.BaseDisplayActivity;
import bb.lanxing.adapter.sport.SportActivityAdapter;
import bb.lanxing.adapter.sport.SportActivityNewSmallAdapter;
import bb.lanxing.calc.calculator.PauseCalc;
import bb.lanxing.calc.data.DisplayPoint;
import bb.lanxing.common.engin.util.EnginUtil;
import bb.lanxing.manager.RemoteServiceManager;
import bb.lanxing.manager.RemoteSharedPreference;
import bb.lanxing.manager.SPConstant;
import bb.lanxing.manager.SharedManager;
import bb.lanxing.model.CurrentLocation;
import bb.lanxing.model.WorkoutDatabaseHelper;
import bb.lanxing.model.database.Event;
import bb.lanxing.model.database.ITrackPoint;
import bb.lanxing.model.database.IWorkout;
import bb.lanxing.model.database.RouteBook;
import bb.lanxing.model.database.Workout;
import bb.lanxing.mvp.view.sport.ItemStyle;
import bb.lanxing.nav.NavEngine;
import bb.lanxing.nav.NavInfoCallback;
import bb.lanxing.nav.NavServiceManager;
import bb.lanxing.network.BiCiCallback;
import bb.lanxing.network.MyHttpClient;
import bb.lanxing.util.BiCiCoorConverter;
import bb.lanxing.util.CalorieUtil;
import bb.lanxing.util.CommonUtil;
import bb.lanxing.util.CountdownAnimationUtil;
import bb.lanxing.util.JsonUtil;
import bb.lanxing.util.Log;
import bb.lanxing.utils.MapUtil;
import bb.lanxing.utils.PanelItemTypeUtil;
import bb.lanxing.view.InfoWindowToBitmap;
import bb.lanxing.view.LongClickProgressView;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

public class SportActivity extends BaseDisplayActivity implements View.OnClickListener, BDLocationListener {
    public static final String EXTRA_LUSHU_ID = "lushuId";
    public static final String EXTRA_TYPE_SPORT = "sportType";
    public static final String EXTRA_TITLE = "title";
    private final static String TAG = SportActivity.class.getSimpleName();
    protected final Object syncLock = new Object();
    public Handler handler = new Handler(Looper.getMainLooper());
    private CoordinatorLayout rootLayout;
    private RelativeLayout mapViewLayout;
    private TextureMapView mMapView;
    private BaiduMap mBaiduMap;
    private CardView navLayout;
    private TextView navInfoText;
    private TextView navClose;
    private ImageButton locationBtn;
    private TextView navigation_start_btn;
    private TextView teamLocBtn;
    // 运动面板
    private RelativeLayout bottom_panel;
    private BottomSheetBehavior bottomSheetBehavior;
    private RecyclerView mSmallPanel;
    private SportActivityNewSmallAdapter mSportActivityNewSmallAdapter = new SportActivityNewSmallAdapter();
    private RelativeLayout mBigPanel;
    private TextView sportTypeText;
    private TextView sportStatus;
    private TextView mSportItemBig;
    private TextView mSportItemBigName;
    private RecyclerView mRecyclerViewBig;
    private SportActivityAdapter mSportActivityAdapter = new SportActivityAdapter();
    private ImageView mStartButton;
    private LongClickProgressView mStopButton;
    // 运动逻辑的后台起始点
    private RemoteServiceManager mRemoteServiceManager = RemoteServiceManager.getInstance();
    // 运动数据的载体
    private DisplayPoint mDisplayPoint;
    // 导航管理类
    private NavServiceManager mNavServiceManager = NavServiceManager.getInstance();
    // 负责更新运动界面的导航的回调
    private NavInfoCallback mNavInfoCallback;
    private LatLng mCurrentLatLng;
    private List<LatLng> realTrackList = new ArrayList<>();
    private List<Double> speedList = new ArrayList<>();
    private MapUtil mapUtil = null;
    // 运行了几秒
    private long mSportTime = 0;
    // 是否timer认为长时间未动后的暂停
    private boolean isTimerPause = false;
    // 是否人为强制暂停
    private boolean isForcedPause = false;
    // 已有几秒小于暂停速度
    private int pauseTime = 0;
    private int direction = 0;
    private boolean isFirst = true;
    private long lushuId;
    private boolean isCompassMode = false;
    private boolean isMapMoved = false;
    private SensorManager mSensorManager;
    private boolean isNavi = false;
    private int sportType = 0;
    private List<Integer> mPanelItemTypeList;
    private int mItemType;
    private Subscription loadWorkoutSubscription;
    private Subscription drawWorkoutSubscription;
    private LinkedList<Overlay> workoutOverlays = new LinkedList<>();

    /**
     * 队友位置对话框的默认选择项
     */
    private int checkedItem = 0;
    /**
     * 已选中进行位置共享的组队ID
     */
    private long mSelectedTeamId;
    /**
     * 进行位置上传和更新的Timer
     */
    private Timer locationShareTimer;

    private boolean orientationSensorSupported = false;
    private LocationClient mLocationClient = null;

    // 用于保存队友位置的 Overlays
    private List<Overlay> teammateOverlays = new ArrayList<>();
    // 更新地图方向
    private SensorEventListener mSensorEventListener = new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent event) {
            direction = (int) event.values[SensorManager.DATA_X];
            if (mDisplayPoint != null) {
                mDisplayPoint.setAzimuth(direction);
            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }
    }; // 真正在更新GPS运动数据

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.logd(TAG, "onCreate");

        setContentView(R.layout.activity_sport);

        LinearLayout countdownLayout = findViewById(R.id.countdownLayout);
        TextView countdown = findViewById(R.id.countdown);
        CountdownAnimationUtil.start(countdownLayout, countdown, this);

        Intent intent = getIntent();
        lushuId = intent.getLongExtra(EXTRA_LUSHU_ID, 0);
        sportType = intent.getIntExtra(EXTRA_TYPE_SPORT, 0);

        rootLayout = findViewById(R.id.rootLayout);
        rootLayout
                .setKeepScreenOn(SharedManager.getInstance().getBoolean(SPConstant.KEY_DASHBOARD_LIGHT_ALWAYS, false));
        mapViewLayout = findViewById(R.id.mapViewLayout);
        mMapView = findViewById(R.id.textureMapView);
        mMapView.removeViewAt(1);
        mBaiduMap = mMapView.getMap();
        // 显示指南针
        mBaiduMap.getUiSettings().setCompassEnabled(true);
        // 开启定位图层
        mBaiduMap.setMyLocationEnabled(true);
        mBaiduMap.setMyLocationConfiguration(
                new MyLocationConfiguration(MyLocationConfiguration.LocationMode.FOLLOWING, true, null));

        navLayout = findViewById(R.id.nav_layout);
        navInfoText = findViewById(R.id.nav_info_text);
        navClose = findViewById(R.id.nav_close);
        navClose.setOnClickListener(this);

        locationBtn = findViewById(R.id.location_btn);
        locationBtn.setOnClickListener(this);

        navigation_start_btn = findViewById(R.id.navigation_start_btn);
        navigation_start_btn.setOnClickListener(this);

        teamLocBtn = findViewById(R.id.team_loc_btn);
        teamLocBtn.setOnClickListener(v -> onTeamClick());

        bottom_panel = findViewById(R.id.bottom_panel);
        bottomSheetBehavior = BottomSheetBehavior.from(bottom_panel);
        float density = getResources().getDisplayMetrics().density;
        bottomSheetBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                ViewGroup.LayoutParams layoutParams = mapViewLayout.getLayoutParams();
                layoutParams.height = (int) (rootLayout.getHeight() - 80 * density - slideOffset * density * 410);
                mapViewLayout.setLayoutParams(layoutParams);
                if (slideOffset > 0.1) {
                    mBigPanel.setVisibility(View.VISIBLE);
                }
                mBigPanel.setAlpha(slideOffset);
                mSmallPanel.setAlpha(1 - slideOffset);
            }
        });

        mSmallPanel = findViewById(R.id.small_panel);
        mSmallPanel.setLayoutManager(new GridLayoutManager(this, 3));
        mSmallPanel.setAdapter(mSportActivityNewSmallAdapter);
        mBigPanel = findViewById(R.id.big_panel);
        sportTypeText = findViewById(R.id.sport_type);
        sportTypeText.setText(getIntent().getStringExtra("title"));
        sportStatus = findViewById(R.id.sport_status);

        mSportItemBig = findViewById(R.id.sport_item_big);
        mSportItemBigName = findViewById(R.id.sport_item_big_name);

        mRecyclerViewBig = findViewById(R.id.big_panel_list);
        mRecyclerViewBig.setLayoutManager(new GridLayoutManager(this, 2));
        mRecyclerViewBig.setAdapter(mSportActivityAdapter);
        updateItemType();

        mStartButton = findViewById(R.id.mStartButton);
        mStartButton.setOnClickListener(view -> {
            if (!isTimerPause) {
                isForcedPause = true;
                pauseSport();
            } else {
                continueSport();
                isForcedPause = false;
            }
        });
        mStopButton = findViewById(R.id.mStopButton);
        mStopButton.setOnLongClickStateListener(new LongClickProgressView.OnLongClickStateListener() {
            @Override
            public void onFinish() {
                new CircleDialog.Builder().setTitle(getString(R.string.text_finish))
                        .setText(getString(R.string.save_content)).setPositive(getString(R.string.text_finish), v -> {
                            stopSport();
                            return true;
                        }).setNegative(getString(R.string.keep_move), v -> {
                            continueSport();
                            isForcedPause = false;
                            return true;
                        }).show(getSupportFragmentManager());
            }

            @Override
            public void onProgress(float progress) {
            }

            @Override
            public void onCancel() {
            }
        });

        mapUtil = MapUtil.getInstance();
        mapUtil.init(mMapView);

        if (lushuId > 0) {
            navigation_start_btn.setVisibility(View.VISIBLE);
            drawSportLushu(mBaiduMap, RouteBook.getById(lushuId), true);
        }

        // 获取传感器管理服务
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        // 导航服务
        mNavInfoCallback = new NavInfoCallback(this);
        mNavServiceManager.registerNavigationCallback(mNavInfoCallback);

        mRemoteServiceManager.registerDisplayPointChangedListener(mDisplayPointChangedListener);
        mRemoteServiceManager.startSport(0, RemoteSharedPreference.getInstance().getSportTypes());
        CalorieUtil.updatePersonalBMR();// update BMR before starting
        setNightMode();
        orientationSensorSupported = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION) != null;
        Log.logi(TAG, "orientationSensorSupported=" + orientationSensorSupported);
        if (!orientationSensorSupported) {
            initBaiduLocation();
        }
    }    private final RemoteServiceManager.DisplayPointChangedListener mDisplayPointChangedListener =
            new RemoteServiceManager.DisplayPointChangedListener() {
                @Override
                public void onPointChanged(DisplayPoint displayPoint) {
                    if (displayPoint != null) {
                        Location location = displayPoint.getLocation();
                        if (location != null) {
                            Log.logi(TAG, "onPointChanged: latitude " + location.getLatitude() + ", longitude "
                                    + location.getLongitude());
                        }
                    }
                    mDisplayPoint = displayPoint;
                    runOnUiThread(() -> handleLocationChanged(mDisplayPoint));
                }
            };

    private void setNightMode() {
        if (SharedManager.getInstance().isNightMode()) {
            bottom_panel.setBackgroundResource(R.drawable.bottem_sheet_bg_night);
            sportTypeText.setTextColor(getColor(R.color.text_night));
            sportStatus.setTextColor(getColor(R.color.text_night));
            mSportItemBig.setTextColor(getColor(R.color.text_night));
            mSportItemBigName.setTextColor(getColor(R.color.text_night));
        }
        ItemStyle itemStyle;
        if (SharedManager.getInstance().isBigFontMode()) {
            itemStyle = ItemStyle.ITEMS_BIG_FONT_STYLE[2][0];
        } else {
            itemStyle = ItemStyle.ITEMS_STYLE[2][0];
        }
        mSportItemBig.setTextSize(itemStyle.textSize);
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.logd(TAG, "onResume");
        mapUtil.onResume();

        updateItemType();

        if (mDisplayPoint != null) {
            cancelLoadWorkout();
            cancelDrawWorkout();
            loadWorkout(mDisplayPoint.getWorkoutId());
        } else {
            Log.logi(TAG, "onResume: mDisplayPoint is null");
        }
        mSensorManager.registerListener(mSensorEventListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                SensorManager.SENSOR_DELAY_UI);
    }

    private void updateItemType() {
        mPanelItemTypeList = PanelItemTypeUtil.loadCache(App.getContext().getUserId(), sportType);
        mSportActivityNewSmallAdapter.updateItem(mPanelItemTypeList);
        mSportActivityAdapter.updateItem(mPanelItemTypeList);
        mItemType = mPanelItemTypeList.get(0);
        mSportItemBig.setText(PanelItemTypeUtil.resetDefault(mItemType));
        mSportItemBigName.setText(PanelItemTypeUtil.getItemName(mItemType));
    }

    @SuppressLint("MissingSuperCall")
    @Override
    public void onBackPressed() {
        toast("请先长按结束按钮，等圆圈转完后，结束运动");
    }

    @Override
    public void onPause() {
        Log.logd(TAG, "onPause");
        mapUtil.onPause();
        mSensorManager.unregisterListener(mSensorEventListener);
        super.onPause();
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.nav_close) {
            navLayout.setVisibility(View.GONE);
            navigation_start_btn.setVisibility(View.VISIBLE);
            switchLocationMode(false);
            if (mNavServiceManager.isNavigating()) {
                mNavServiceManager.unbindService();
                toast(R.string.nav_stop);
            }
            isNavi = false;
        } else if (v.getId() == R.id.location_btn) {
            if (isMapMoved) {
                mapUtil.updateStatus(mCurrentLatLng, true);
                locationBtn.setImageResource(R.drawable.ic_location_1);
            } else {
                switchLocationMode(!isCompassMode);
            }
        } else if (v.getId() == R.id.navigation_start_btn) {
            navLayout.setVisibility(View.VISIBLE);
            navigation_start_btn.setVisibility(View.GONE);
            switchLocationMode(true);
            mNavServiceManager.launchNav(lushuId, true);
            isNavi = true;
        }
    }

    private void switchLocationMode(boolean isCompassMode0) {
        isCompassMode = isCompassMode0;
        if (!isCompassMode) {
            locationBtn.setImageResource(R.drawable.ic_location_1);
            mBaiduMap.setMyLocationConfiguration(
                    new MyLocationConfiguration(MyLocationConfiguration.LocationMode.FOLLOWING, true, null));
            mBaiduMap.animateMapStatus(
                    MapStatusUpdateFactory.newMapStatus(new MapStatus.Builder().rotate(0).overlook(0).build()));
        } else {
            locationBtn.setImageResource(R.drawable.ic_location_2);
            mBaiduMap.setMyLocationConfiguration(
                    new MyLocationConfiguration(MyLocationConfiguration.LocationMode.COMPASS, true, null));
            // 切换到3D视图
            mBaiduMap.animateMapStatus(
                    MapStatusUpdateFactory.newMapStatus(new MapStatus.Builder().overlook(-45).build()));
        }
    }

    private void handleLocationChanged(DisplayPoint displayPoint) {
        if (mMapView == null || displayPoint == null) {
            return;
        }
        Location location = displayPoint.getLocation();
        if (location == null) {
            return;
        }

        if (!CommonUtil.isPointValid(location.getLatitude(), location.getLongitude()) || location.getAccuracy() > 500.0f
                || location.getAccuracy() < 0.0f) {
            return;
        }

        LatLng latLngSystem = new LatLng(location.getLatitude(), location.getLongitude());
        mCurrentLatLng = BiCiCoorConverter.earth2Baidu(latLngSystem);
        if (null == mCurrentLatLng) {
            return;
        }
        CurrentLocation.latitude = mCurrentLatLng.latitude;
        CurrentLocation.longitude = mCurrentLatLng.longitude;
        if (null != mapUtil && isFirst) {
            mBaiduMap.animateMapStatus(MapStatusUpdateFactory
                    .newMapStatus(new MapStatus.Builder().zoom(18.0f).target(mCurrentLatLng).build()));
            isFirst = false;
            realTrackList.add(mCurrentLatLng);
            speedList.add(0.0);
        }
        mBaiduMap.setMyLocationData(new MyLocationData.Builder().direction(direction).latitude(mCurrentLatLng.latitude)
                .longitude(mCurrentLatLng.longitude).build());
        float speed = location.getSpeed();
        isSportPaused(speed);
        if (!isFirst) {
            realTrackList.add(mCurrentLatLng);
            speedList.add((double) speed);
        }
        if (realTrackList != null && realTrackList.size() > 1) {
            mapUtil.drawPolyline(realTrackList, speedList);
        }
        mSportItemBig.setText(PanelItemTypeUtil.getItemValue(displayPoint, mItemType));
        mSportActivityNewSmallAdapter.updateData(displayPoint);
        mSportActivityAdapter.updateData(displayPoint);

        if (isNavi) {
            NavEngine.getInstance().onRefreshLocation(location.getLatitude(), location.getLongitude(),
                    location.getSpeed());
        }
    }

    private void isSportPaused(float speed) {
        Log.d(TAG, "isSportPaused...pauseTime=" + pauseTime + ", mSportTime=" + mSportTime + ", speed=" + speed);
        if (isForcedPause) {
            return;
        }
        if (speed > PauseCalc.getNotMovingSpeed(sportType)) {
            mSportTime++;
            if (isTimerPause) {
                continueSport();
            }
        } else {
            if (isTimerPause) {
                return;
            }
            pauseTime++;
            if (pauseTime >= PauseCalc.getNotMovingCount(sportType)) {
                pauseSport();
            }
        }
    }

    public void updateNavInfo(int type, String msg, double distance) {
        navInfoText.setText(msg);
    }

    public void updateYaw(boolean yaw) {
        navInfoText.setText(yaw ? R.string.navigation_yaw : R.string.navigating);
    }

    public void onNavigationFailed(int code) {
        if (code >= 50) {
            toast("导航 错误: " + code);
        } else if (App.getContext().isDebugMode()) {
            toast("导航 错误: " + code);
        }
    }

    @Override
    protected void onRefreshUI(DisplayPoint displayPoint) {
        if ((sportType == Workout.TYPE_TRAINING) || (sportType == Workout.TYPE_INDOOR_BIKE)
                || (sportType == Workout.TYPE_BIKE_TRAINER) || (sportType == Workout.TYPE_ROWER)
                || (sportType == Workout.TYPE_CROSS_TRAINER)) {
            Log.logd(TAG, "onRefreshUI,it is training mode or indoor bike");
            sportStatus.setVisibility(View.GONE);
            mSportItemBig.setText(PanelItemTypeUtil.getItemValue(displayPoint, mItemType));
            mSportActivityNewSmallAdapter.updateData(displayPoint);
            mSportActivityAdapter.updateData(displayPoint);
        } else {
            Log.logd(TAG, "onRefreshUI,it is not training mode");
        }
    }

    public void loadWorkout(long workoutId) {
        Log.logi(TAG, "loadWorkout: " + workoutId);
        if (workoutId <= 0) {
            return;
        }
        Subscription subscribe = Observable.just(workoutId).subscribeOn(Schedulers.newThread())
                .flatMap(workoutId2 -> Observable.just(WorkoutDatabaseHelper.queryWorkoutById(workoutId2)))
                .observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                    }

                    @Override
                    public void onNext(Workout workout) {
                        drawWorkout(workout, false, true);
                    }
                });
        loadWorkoutSubscription = subscribe;
        addSubscription(subscribe);
    }

    private void drawWorkout(final IWorkout workout, final boolean isStatic, final boolean clearOld) {
        if (workout == null) {
            return;
        }
        Subscription subscribe = Observable.just(workout).subscribeOn(Schedulers.io()).flatMap(this::fetchTrackPoints)
                .map(this::convertTrackPointsToLatLng) // 数据转换
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(workoutPoints -> drawOnMap(workoutPoints, isStatic, clearOld));
        addSubscription(subscribe);
        drawWorkoutSubscription = subscribe;
    }

    // 提取 TrackPoints 数据
    private Observable<List<ITrackPoint>> fetchTrackPoints(IWorkout workout) {
        return Observable.just(workout.getByWorkoutForMap(workout.getLocSource()));
    }

    // 转换 TrackPoints 为 LatLng 列表
    private List<LatLng> convertTrackPointsToLatLng(List<ITrackPoint> trackPoints) {
        List<LatLng> latLngList = new ArrayList<>();
        for (ITrackPoint point : trackPoints) {
            latLngList.add(BiCiCoorConverter.earth2Baidu(point.getLatLng()));
        }
        return latLngList;
    }

    // 在地图上绘制数据
    private void drawOnMap(List<LatLng> workoutPoints, boolean isStatic, boolean clearOld) {
        List<Overlay> overlays = null;
        Log.logi(TAG,
                "current Thread = " + Thread.currentThread() + ", clearOld = " + clearOld + ", isStatic = " + isStatic);
        if (clearOld) {
            clearOverlay();
        }
        if (isStatic) {
            overlays = bb.lanxing.util.MapUtil.drawStaticWorkout(mBaiduMap, workoutPoints);
        } else {
            if (workoutPoints != null) {
                Log.logi(TAG, "drawOnMap:workoutPoints.size() = " + workoutPoints.size());
            }
            if (workoutPoints != null && workoutPoints.size() > 1) {
                List<Overlay> drawSportWorkout = bb.lanxing.util.MapUtil.drawSportWorkout(mBaiduMap, workoutPoints);
                if (drawSportWorkout != null && !drawSportWorkout.isEmpty()) {
                    Log.logi(TAG, "drawOnMap: drawSportWorkout.size() = " + drawSportWorkout.size());
                }
                overlays = drawSportWorkout;
                LatLng newLatLng = workoutPoints.get(workoutPoints.size() - 1);
                mBaiduMap.setMyLocationData(new MyLocationData.Builder().latitude(newLatLng.latitude)
                        .longitude(newLatLng.longitude).build());
                realTrackList.add(newLatLng);
                speedList.add(0.0);
            }
        }

        if (overlays != null && !overlays.isEmpty()) {
            synchronized (syncLock) {
                workoutOverlays.addAll(overlays);
            }
        }
    }

    private synchronized boolean clearOverlay() {
        boolean removed = false;
        Iterator<Overlay> iterator = workoutOverlays.iterator();
        while (iterator.hasNext()) {
            removeOverlay(iterator.next());
            removed = true;
        }
        realTrackList.clear();
        speedList.clear();
        workoutOverlays.clear();
        return removed;
    }

    private void removeOverlay(Overlay overlay) {
        if (overlay == null) {
            return;
        }
        try {
            overlay.remove();
        } catch (Exception e) {
            Log.w(TAG, "removeOverlay: " + e.getMessage());
        }
    }

    private void cancelLoadWorkout() {
        if (loadWorkoutSubscription != null) {
            cancelSubscription(loadWorkoutSubscription);
            loadWorkoutSubscription = null;
        }
    }

    private void cancelDrawWorkout() {
        if (drawWorkoutSubscription != null) {
            cancelSubscription(drawWorkoutSubscription);
            drawWorkoutSubscription = null;
        }
    }

    private void onTeamClick() {
        if (App.getContext().isUserSignin()) {
            MyHttpClient.requestMyActivities(new BiCiCallback(this) {
                @Override
                public void onResponseString(@NonNull String string) {
                    try {
                        JSONArray jSONArray = new JSONObject(string).getJSONArray("rows");
                        List<Event> eventList = new ArrayList<>();
                        for (int i = 0; i < jSONArray.length(); i++) {
                            Event createByJson = Event.createByJson(jSONArray.getJSONObject(i));
                            eventList.add(createByJson);
                        }
                        runOnUiThread(() -> showTeamlistDialog(eventList));
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, 1, 100, 1);
        } else {
            App.getContext().userSignin();
        }
    }

    private void showTeamlistDialog(List<Event> eventList) {
        if (eventList.size() > 0) {
            String[] teamNames = new String[eventList.size() + 1];
            teamNames[0] = "不显示队友位置";
            for (int i = 0; i < eventList.size(); i++) {
                teamNames[i + 1] = eventList.get(i).getTitle();
            }
            new AlertDialog.Builder(SportActivity.this).setTitle(R.string.map_show_teammate_location)
                    .setSingleChoiceItems(teamNames, checkedItem, (dialog, which) -> {
                        checkedItem = which;
                        dialog.dismiss();
                        mBaiduMap.clear();
                        if (lushuId > 0) {
                            drawSportLushu(mBaiduMap, RouteBook.getById(lushuId), true);
                        }
                        if (checkedItem > 0) {
                            teamLocBtn.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_v1_friends_checked, 0,
                                    0);
                            mSelectedTeamId = eventList.get(which - 1).getEventId();
                            startUploadTimer();
                        } else {
                            teamLocBtn.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_v1_friends_normal, 0,
                                    0);
                            stopUploadTimer();
                        }
                    }).show();
        } else {
            Toast.makeText(SportActivity.this, "请去组队页面，打开你参加的组队的位置共享开关", Toast.LENGTH_LONG).show();
        }
    }

    private void loadTeamLocation() {
        BiCiCallback biCiCallback = new BiCiCallback() {
            @Override
            public void onResponseString(@NonNull String string) {
                closePopWindow();
                // 清除队友旧的位置
                for (Overlay overlay : teammateOverlays) {
                    overlay.remove();
                }
                teammateOverlays.clear();
                try {
                    JSONArray jSONArray = new JSONObject(string).getJSONArray("memberInfo");
                    for (int i = 0; i < jSONArray.length(); i++) {
                        JSONObject memberInfo = jSONArray.getJSONObject(i);
                        String nickName = JsonUtil.getStringValue("nickName", memberInfo);
                        if (JsonUtil.getIntegerValue("userId", memberInfo) == App.getContext().getUserId()) {
                            continue;
                        }
                        JSONObject myLocation = memberInfo.getJSONObject("myLocation");
                        double latitude = JsonUtil.getDoubleValue("latitude", myLocation);
                        double longitude = JsonUtil.getDoubleValue("longitude", myLocation);
                        Overlay overlay =
                                mBaiduMap.addOverlay(new MarkerOptions().position(new LatLng(latitude, longitude))
                                        .icon(InfoWindowToBitmap.getBitmapDescriptor(nickName, getResources())));
                        teammateOverlays.add(overlay);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        };
        MyHttpClient.requestActivityDetail(biCiCallback, mSelectedTeamId);
    }

    private void startUploadTimer() {
        BiCiCallback callback = new BiCiCallback() {
            @Override
            public void onResponseString(@NonNull String string) throws JSONException {
            }
        };

        if (locationShareTimer == null) {
            locationShareTimer = new Timer();
            locationShareTimer.schedule(new TimerTask() {
                @Override
                public void run() {
                    if (mCurrentLatLng != null) {
                        MyHttpClient.uploadMyLoation(callback, mCurrentLatLng, null, null, 0, 5000);
                    }
                    loadTeamLocation();
                }
            }, 0L, 5000);
        }
    }

    private void stopUploadTimer() {
        if (locationShareTimer != null) {
            locationShareTimer.cancel();
            locationShareTimer.purge();
            locationShareTimer = null;
        }
    }

    private void pauseSport() {
        isTimerPause = true;
        pauseTime = 0;
        if (isForcedPause) {
            mRemoteServiceManager.pauseSportByUser(true);
            mRemoteServiceManager.unregisterDisplayPointChangedListener(mDisplayPointChangedListener);
        }
        sportStatus.setText("| " + getString(R.string.move_pause));
        mStartButton.setImageResource(R.drawable.ic_start);
        int offset = ConvertUtils.dp2px(100);
        ObjectAnimator.ofFloat(mStartButton, "translationX", 0, -offset).start();
        ObjectAnimator.ofFloat(mStopButton, "translationX", 0, offset).start();
    }

    private void continueSport() {
        isTimerPause = false;
        if (isForcedPause) {
            mRemoteServiceManager.pauseSportByUser(false);
            mRemoteServiceManager.registerDisplayPointChangedListener(mDisplayPointChangedListener);
        }
        sportStatus.setText("");
        mStartButton.setImageResource(R.drawable.ic_pause);
        int offset = ConvertUtils.dp2px(100);
        ObjectAnimator.ofFloat(mStartButton, "translationX", -offset, 0).start();
        ObjectAnimator.ofFloat(mStopButton, "translationX", offset, 0).start();
    }

    private void stopSport() {
        isTimerPause = true;
        long workoutId = mDisplayPoint.getWorkoutId();
        if ((workoutId > 0) && (mDisplayPoint.getDistance() > Utils.DOUBLE_EPSILON
                || (mDisplayPoint.getSportType() == Workout.TYPE_TRAINING && mDisplayPoint.getDuration() > 0)
                || (mDisplayPoint.getSportType() == Workout.TYPE_CROSS_TRAINER && mDisplayPoint.getDuration() > 0)
                || (mDisplayPoint.getSportType() == Workout.TYPE_BIKE_TRAINER && mDisplayPoint.getDuration() > 0)
                || (mDisplayPoint.getSportType() == Workout.TYPE_ROWER && mDisplayPoint.getDuration() > 0)
                || (mDisplayPoint.getSportType() == Workout.TYPE_INDOOR_BIKE && mDisplayPoint.getDuration() > 0))) {
            Intent intent = new Intent(SportActivity.this, SportFinishActivity.class);
            intent.putExtra("workoutId", workoutId);
            startActivity(intent);
        }
        mapUtil.clear();
        realTrackList.clear();
        speedList.clear();
        workoutOverlays.clear();
        mSensorManager.unregisterListener(mSensorEventListener);

        mNavServiceManager.unregisterNavigationCallback(mNavInfoCallback);
        mNavInfoCallback = null;

        mRemoteServiceManager.stopSport();
        mRemoteServiceManager.unregisterDisplayPointChangedListener(mDisplayPointChangedListener);

        stopUploadTimer();
        finish();
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.logd(TAG, "onStart");
        realTrackList.clear();
        startBaiduLocation();
    }

    @Override
    protected void onStop() {
        super.onStop();
        stopBaiduLocation();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterBaiduLocation();
        teammateOverlays.clear();

        mNavServiceManager.unbindService();
    }

    private void initBaiduLocation() {
        try {
            LocationClient.setAgreePrivacy(true);
            mLocationClient = new LocationClient(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
        LocationClientOption locationClientOption = new LocationClientOption();
        locationClientOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        locationClientOption.setScanSpan(2000);
        locationClientOption.setOpenGps(true);
        locationClientOption.setEnableSimulateGnss(EnginUtil.isAPKDebugable(this));
        locationClientOption.setCoorType("gcj02");
        locationClientOption.setIsNeedAddress(false);
        mLocationClient.registerLocationListener(this);
        mLocationClient.setLocOption(locationClientOption);
    }

    private void startBaiduLocation() {
        if (mLocationClient != null) {
            mLocationClient.start();
        }
    }

    private void stopBaiduLocation() {
        if (mLocationClient != null && mLocationClient.isStarted()) {
            mLocationClient.stop();
        }
    }

    private void unregisterBaiduLocation() {
        if (mLocationClient != null) {
            mLocationClient.unRegisterLocationListener(this);
            mLocationClient = null;
        }
    }

    @Override
    public void onReceiveLocation(BDLocation location) {
        if (location == null) {
            return;
        }

        BDLocation baiduLocation = new BDLocation(location);
        // Log.logd(TAG, "baidu onReceiveLocation : "
        // + baiduLocation.getLatitude() + ", " + baiduLocation.getLongitude()
        // + ", " + baiduLocation.getCoorType() + " " + baiduLocation.getDirection());

        if (!CommonUtil.isPointValid(baiduLocation.getLatitude(), baiduLocation.getLongitude())
                || baiduLocation.getRadius() > 500.0f || baiduLocation.getRadius() < 0.0f) {
            return;
        }

        direction = (int) baiduLocation.getDirection();
        // BDLocation convertedLocation;
        // if (LocCountry.inTW_HK(baiduLocation.getLatitude(), baiduLocation.getLongitude())) {
        // convertedLocation = baiduLocation;
        // } else {
        // convertedLocation = BiCiCoorConverter.common2Baidu(baiduLocation);
        // }
        // mBaiduMap.setMyLocationData(new MyLocationData.Builder()
        // .latitude(convertedLocation.getLatitude())
        // .longitude(convertedLocation.getLongitude())
        // .accuracy(convertedLocation.getRadius())
        // .direction(convertedLocation.getDirection())
        // .build());
    }



}
